package Navi_run;

import encryption.Hash;
import it.unisa.dia.gas.jpbc.Element;

import java.math.BigInteger;
import java.security.SecureRandom;

import static encryption.RSA.generateRsaKeyPair;
import static parameter.parameter_length.*;

public class entity_register {
    public static void driverSendRegisterRequest() throws Exception {
        // 司机获取一个RSA公私钥
        TA_driver.RSA_driver = generateRsaKeyPair();
        //假设司机有一个唯一身份uuid rdi 司机将rdi和ni ni2签名后发给服务器
        String rdi = "123456";
        //获取随机si
        SecureRandom secureRandom = new SecureRandom();
        BigInteger si =new  BigInteger(si_length,secureRandom);
        TA_driver.si = si;
        //生成ni 和ni2(ni上多一波浪线)
        Element ni = params.gpk_g2.pow(si).getImmutable();
        Element ni2 = params.gpk_B.pow(si).getImmutable();
        TA_driver.rdi = rdi;
        TA_driver.ni = ni.getImmutable();
        TA_driver.ni2 = ni2.getImmutable();
        System.out.println("司机发起注册请求完成");

    }
    //服务器响应司机注册请求
    public static void TaResponseDriverRegist(){
        //服务器进行校验
        //RSA签名暂时不验证，和服务器联调时候验证
        SecureRandom secureRandom = new SecureRandom();
        if (params.pairing.pairing(TA_driver.ni, params.gpk_B).isEqual(params.pairing.pairing(params.gpk_g2,TA_driver.ni2))) {
            //零知识证明暂时略过
            //TA存储rdi,ni,xigema,ni2
            TA_driver.TA_rdi = TA_driver.rdi;
            TA_driver.TA_ni = TA_driver.ni.getImmutable();
            TA_driver.TA_ni2 = TA_driver.ni2.getImmutable();
            TA_driver.TA_xigema = TA_driver.xigema;
            //获取随机t
            BigInteger t = new BigInteger(t_length,secureRandom);
            TA_driver.t = t;
            //生成Eird (Ei1,Ei2)
            Element Ei1 = params.gpk_g2.pow(t).getImmutable();
            Element Ei2 = (((params.gpk_g2.pow(params.gsk_a)).mul(TA_driver.ni.pow(params.gsk_b))).pow(t)).getImmutable();
            //TA发送Ei1,Ei2,SK,K,HKP给rdi
            TA_driver.Ei1 = Ei1.getImmutable();
            TA_driver.Ei2 = Ei2.getImmutable();


            TA_driver.SK1 = params.SK1;
            TA_driver.SK2 = params.SK2;
            TA_driver.V = params.V;
            TA_driver.HKP = params.HKP;
            TA_driver.K = secureRandom.nextInt();
            System.out.println("服务器成功验证并响应注册请求");
        } else {
            System.out.println("司机注册服务器验证失败");
        }
    }
    public static void driver_receive(){
        //司机存储
        TA_driver.driver_Ei1 = TA_driver.Ei1;
        TA_driver.driver_Ei2 = TA_driver.Ei2;
        TA_driver.driver_SK1 = TA_driver.SK1;
        TA_driver.driver_SK2 = TA_driver.SK2;
        TA_driver.driver_V = TA_driver.V;
        TA_driver.driver_HKP = TA_driver.HKP;
        TA_driver.driver_K = TA_driver.K;
        //初始化rc = 1
        TA_driver.driver_rc = 1;
    }
    public static void rsu_register(){

    }
    public static void nsp_register(){

    }
    public static void TestZPKP(BigInteger e,BigInteger s,BigInteger v,BigInteger F){
        //这里每次生成一次Y Z  X然后发送给服务器
        //因为零知识证明有三个量  所以生成XYZ
        SecureRandom secureRandom = new SecureRandom();
        BigInteger Y = new BigInteger(YZX_length,secureRandom);
        BigInteger Z = new BigInteger(YZX_length,secureRandom);
        BigInteger X = new BigInteger(YZX_length,secureRandom);
        //生成M
        BigInteger M = (Y.modPow(e,F).multiply(Z.modPow(s,F).multiply(X.modPow(v,F)))).mod(F);
        //随机生成a b c
        BigInteger a = new BigInteger(abc_length,secureRandom);
        BigInteger b = new BigInteger(abc_length,secureRandom);
        BigInteger c = new BigInteger(abc_length,secureRandom);
        BigInteger daierta = (Y.modPow(a,F).multiply(Z.modPow(b,F).multiply(X.modPow(c,F)))).mod(F);
        BigInteger n = new BigInteger(Hash.sha256(Y.toString()+Z.toString()+X.toString()+M.toString()+daierta.toString()));

        BigInteger a1 = n.multiply(e).add(a);
        BigInteger b1 = n.multiply(s).add(b);
        BigInteger c1 = n.multiply(v).add(c);

        BigInteger temp1 = (M.modPow(n,F).multiply(daierta)).mod(F);
        BigInteger temp2 = (Y.modPow(a1,F).multiply(Z.modPow(b1,F).multiply(X.modPow(c1,F)))).mod(F);

//        System.out.println(temp1);
//        System.out.println(temp2);

    }

}
